//
//  AnimationMediaTimingViewController.m
//  CoreAnimation
//
//  Created by 张国文 on 16/10/28.
//  Copyright © 2016年 hangzhouyijiyin. All rights reserved.
//

#import "AnimationMediaTimingViewController.h"

@interface AnimationMediaTimingViewController ()

@property (nonatomic, strong) UIView *backgroundView;

@property (nonatomic, strong) UIImageView *imageV;

@property (nonatomic, strong) CALayer *imageLayer;

@property (nonatomic, strong) CALayer *colorLayer;


@end

@implementation AnimationMediaTimingViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];
    
    self.backgroundView = [[UIView alloc] initWithFrame:self.view.frame];
    self.backgroundView.backgroundColor = [UIColor colorWithRed:150 / 255.0 green:150 / 255.0 blue:150 / 255.0 alpha:1];
    [self.view addSubview:_backgroundView];
    
    UILabel *layerLabel = [[UILabel alloc] initWithFrame:CGRectMake(30, 10, 150, 30)];
    layerLabel.text = @"CALayer";
    layerLabel.backgroundColor = [UIColor whiteColor];
    layerLabel.textColor = [UIColor redColor];
    [self.backgroundView addSubview:layerLabel];
    
    UILabel *viewLabel = [[UILabel alloc] initWithFrame:CGRectMake(30, 150, 150, 30)];
    viewLabel.text = @"UIView";
    viewLabel.backgroundColor = [UIColor whiteColor];
    viewLabel.textColor = [UIColor redColor];
    [self.backgroundView addSubview:viewLabel];
    
    self.imageLayer = [CALayer layer];
    self.imageLayer.frame = CGRectMake(30, 50, 80, 80);
    self.imageLayer.contents = (__bridge id _Nullable)([UIImage imageWithName:@"蒙版"].CGImage);
    [self.backgroundView.layer addSublayer:_imageLayer];
    
    self.imageV = [[UIImageView alloc] initWithFrame:CGRectMake(30, 200, 80, 80)];
    self.imageV.image = [UIImage imageWithName:@"蒙版"];
    [self.backgroundView addSubview:_imageV];
    
    self.colorLayer = [CALayer layer];
    self.colorLayer.frame = CGRectMake(100, 300, 80, 80);
    self.colorLayer.backgroundColor = [UIColor blueColor].CGColor;
    [self.backgroundView.layer addSublayer:_colorLayer];
    
    UIButton *transcationButton = [UIButton buttonWithType:UIButtonTypeCustom];
    transcationButton.frame = CGRectMake(0, 400, 375, 30);
    transcationButton.backgroundColor = [UIColor whiteColor];
    [transcationButton setTitle:@"CATranscation的MediaTiming-隐式动画" forState:UIControlStateNormal];
    [transcationButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
    [transcationButton addTarget:self action:@selector(transcationStart:) forControlEvents:UIControlEventTouchUpInside];
    [self.backgroundView addSubview:transcationButton];
    
    
    UIButton *UIViewButton = [UIButton buttonWithType:UIButtonTypeCustom];
    UIViewButton.frame = CGRectMake(0, 450, 375, 30);
    UIViewButton.backgroundColor = [UIColor whiteColor];
    [UIViewButton setTitle:@"UIView的Block MediaTiming-隐式动画" forState:UIControlStateNormal];
    [UIViewButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
    [UIViewButton addTarget:self action:@selector(UIViewStart:) forControlEvents:UIControlEventTouchUpInside];
    [self.backgroundView addSubview:UIViewButton];
    
    UIButton *caAnimationButton = [UIButton buttonWithType:UIButtonTypeCustom];
    caAnimationButton.frame = CGRectMake(0, 500, 375, 30);
    caAnimationButton.backgroundColor = [UIColor whiteColor];
    [caAnimationButton setTitle:@"CAAnimation的MediaTiming-显式动画" forState:UIControlStateNormal];
    [caAnimationButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
    [caAnimationButton addTarget:self action:@selector(CAAnimationStart:) forControlEvents:UIControlEventTouchUpInside];
    [self.backgroundView addSubview:caAnimationButton];
    
    UIButton *frameMediaTimingButton = [UIButton buttonWithType:UIButtonTypeCustom];
    frameMediaTimingButton.frame = CGRectMake(0, 550, 375, 30);
    frameMediaTimingButton.backgroundColor = [UIColor whiteColor];
    [frameMediaTimingButton setTitle:@"CAKeyFrameAnimation的MediaTiming-显式动画" forState:UIControlStateNormal];
    [frameMediaTimingButton sizeToFit];
    [frameMediaTimingButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
    [frameMediaTimingButton addTarget:self action:@selector(frameMediaTimingStart:) forControlEvents:UIControlEventTouchUpInside];
    [self.backgroundView addSubview:frameMediaTimingButton];
    
    
}

/**
 *    隐式动画包括：CATranscation和UIView的block和UIView的begin、commit动画
 其中CATranscation动画速度默认为：kCAMediaTimingFunctionDefault（和kCAMediaTimingFunctionEaseInEaseOut非常相似）
 UIView的动画速度默认为：UIViewAnimationOptionCurveEaseInOut
 显式动画： CAAnmation(所有CAAnimation子类都可设置：CATransition、CABasicAnimaiton、CAKeyframeAnimation)，默认的速度为kCAMediaTimingFunctionLinear(线性均速)
 
 显式动画和隐式动画的区别：显示动画在动画完成以后会自动回到动画开始之前的状态(并且这个恢复的时间为0，就是瞬间)，隐式动画在动画完成之后不会自动回到动画开始之前的状态，除非手动设置，这里需要注意的是： 所有动画(显式和隐式)的执行时间默认都为0.25秒，如果使用CATranscation的函数setCompletionBlock的话，执行时间为0.25秒，但是UIView的completion执行时间为0秒。CAAnimation的默认执行时间为0秒。
 一般来说：自定义CALayer的动画运用CAAnimation和CATranscation，而UIView以及UIView的关联图层运用UIView的block执行动画(隐式动画来执行)。
 
 所有动画执行时间默认为0.25秒是因为  Core Animation在每个run loop周期中自动开始一次新的事务（run loop是iOS负责收集用户输入，处理定时器或者网络事件并且重新绘制屏幕的东西），即使你不显式的用[CATransaction begin]开始一次事务,只写[CATransaction commit]，任何在一次run loop循环中属性的改变都会被集中起来，然后做一次0.25秒的动画。
 
 ⚠️⚠️⚠️结论：视图的position和center始终是重合的，并且一旦视图初始化完毕就不会在改变，除非手动改变positon或center或frame，即通过view的transform或者afffineTransform或者layer的transform达到的视图变化不会影响postion和center；frame即视图的可视范围在哪里就是哪里，是会变的;
 
 使用显示动画的时候，视图的frame是不会改变的(即使你将fillModel = kCAFillModeForwards， removedOnCompletion = NO) ，这个只是保留了图形最后运动的位置，实际上视图的frame和layer的frame没有改变，但是position和center、anchorPoint没有改变。
 
 隐式动画，视图的frame是会改变的，因此你会发现你将一个button运用显式动画移动位置以后，点击的时候不会发生回调，就是因为button的frame还在原来的位置，视图的frame和layer的frame改变，但是position和center、anchorPoint没有改变。
 */



// layer的隐式MediaTiming动画
- (void)transcationStart:(UIButton *)button
{
    // 对于隐式动画，动画速度默认为kCAMediaTimingFunctionDefault（和kCAMediaTimingFunctionEaseInEaseOut非常相似）
    [CATransaction begin];
    [CATransaction setAnimationDuration:2.0];
    [CATransaction setCompletionBlock:^{
        self.imageLayer.affineTransform = CGAffineTransformIdentity;
    }];
 //   [CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
    self.imageLayer.affineTransform = CGAffineTransformMakeTranslation(250, 0);
    [CATransaction commit];
    
}

// UIView的隐式MediaTiming动画
- (void)UIViewStart:(UIButton *)button
{
    [UIView animateWithDuration:2.0 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        self.imageV.transform = CGAffineTransformMakeTranslation(250, 0);
       // self.imageV.layer.affineTransform = CGAffineTransformMakeTranslation(250, 0); // 关联图层
        // 上面两个方法都可以完成动画
    } completion:^(BOOL finished) {
        self.imageV.transform = CGAffineTransformIdentity; // 瞬间恢复
    }];
}

// 显式动画的MediaTiming
- (void)CAAnimationStart:(UIButton *)button
{
    // 对于CAAnimation(显示)动画，动画速度默认为kCAMediaTimingFunctionLinear(线性均速)
        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"];
       animation.duration = 2.0;
        animation.toValue = @(250);
     //   [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
        [self.imageLayer addAnimation:animation forKey:nil];
}

// 帧动画的MediaTiming
- (void)frameMediaTimingStart:(UIButton *)button
{
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"backgroundColor"];
    animation.duration = 4.0;
    animation.values = @[(__bridge id)[UIColor blueColor].CGColor, (__bridge id)[UIColor redColor].CGColor, (__bridge id)[UIColor greenColor].CGColor, (__bridge id)[UIColor blueColor].CGColor];
    CAMediaTimingFunction *fuc = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    animation.timingFunctions = @[fuc, fuc, fuc];
    [self.colorLayer addAnimation:animation forKey:@"changeColor"];
}

@end
